好的!重新回歸到「從巨人的 Tip 看 Angular」系列,今天要分享的 Tip 是透過 ComponentFactoryResolver 來建立一個能夠動態將 component 實體化並 append 到 DOM 的載入器 ?
↑ Image 1
貓咪可愛!
今天的 Tip 會透過一個 directive 來實作,並稱他叫做 AnchorDirective,因為在我的範例中,這個 directive 就是扮演著「錨點」的角色,提供插入 component 元素的定位點功能。
另外新增了 4 個 component,分別是:
@Directive({
selector: '[anchor]',
})
export class AnchorDirective {
constructor(
private viewContainerRef: ViewContainerRef,
private cmpFactoryResolver: ComponentFactoryResolver,
private injector: Injector
) {}
// ... 下接 Block 2
}
↑ Block 1
今天實作的重點有兩個,第一個是 ViewContainerRef
、第二個則是 ComponentFactoryResolver
。
ViewContainerRef 這個類別的功能其實就如同它的名稱一樣,可以包含一個或是多個 view,就如同容器一般。而透過 createComponent
這個方法,開發者可以在容器上建立出新的 component。當在 directive 上使用 DI 取得 ViewContainerRef 的物件實體時,它所提供的 view container 的會是 directive host element 的 view container。
ComponentFactoryReolver 則是負責解析出 component 的工廠方法,這個工廠方法可以提供給 ViewContainerRef,用於 render component。
loadComponent(componentClass: Type<StyleComponent>, data: StyleData): void {
this.viewContainerRef.clear();
const cmpFactory = this.cmpFactoryResolver
.resolveComponentFactory<StyleComponent>(componentClass);
const cmp = this.viewContainerRef
.createComponent<StyleComponent>(cmpFactory, 0, this.injector);
Object.entries(data).forEach(([key, value]) => {
cmp.instance[key] = value;
});
}
↑ Block 2
Block 2 的程式碼就是所有的實作內容。
首先只要呼叫了這個方法,就會先清空 view container 的所有元素,因為我的功能需求是替換掉現在 view container 的內容,而不是不斷新增新的 component 到 container 內。
清空內容之後,再來會透過 ComponentFactoryResolver 的 resolveComponentFactory
來解析 component 的工廠方法,這部分我們有機會再提,目前只需要知道在呼叫這個方法之後,Angular 會產生一個物件,裡面會包含這個 component 的 definition、type、ngModule、selector 等 render 時所需要的所有資訊。
接著就是透過 ViewContainerRef 的 createComponent
方法來 render 一個完整的 component 到 view container 內。
最後的一個步驟則是處理 component 的 property。
接著就可以在 template 內使用囉:
<button
mat-raised-button
color="accent"
*ngFor="let cmpObj of cmpList"
(click)="changeComponent(cmpObj.cmp)"
>
Style {{ cmpObj.name }}
</button>
<ng-template anchor></ng-template>
以上就是今天要介紹的 Tip,透過 ViewContainerRef 與 ComponentFactoryResolver 就可以達成動態插入 component 的功能囉 ?
以下按照入團順序列出我們團隊夥伴的系列文章!
請自由參閱 ?